{% extends 'base.html' %}
{% load static %}

{% block title %}系统日志 - CFS Web System{% endblock %}

{% block page_type %}analytics-logs{% endblock %}

{% block breadcrumb_items %}
<li class="breadcrumb-item"><a href="{% url 'dashboard:dashboard' %}">仪表板</a></li>
<li class="breadcrumb-item"><a href="{% url 'analytics:dashboard' %}">数据分析</a></li>
<li class="breadcrumb-item active">系统日志</li>
{% endblock %}

{% block content %}
<!-- 日志过滤器 -->
<div class="row mb-4">
    <div class="col-12">
        <div class="card">
            <div class="card-header">
                <div class="d-flex justify-content-between align-items-center">
                    <h6 class="mb-0">
                        <i class="fas fa-filter me-2"></i>日志过滤
                    </h6>
                    <div class="d-flex gap-2">
                        <button type="button" class="btn btn-outline-secondary btn-sm" onclick="resetFilters()">
                            <i class="fas fa-undo"></i> 重置
                        </button>
                        <button type="button" class="btn btn-outline-primary btn-sm" onclick="exportLogs()">
                            <i class="fas fa-download"></i> 导出
                        </button>
                    </div>
                </div>
            </div>
            <div class="card-body">
                <form id="log-filter-form" class="row g-3">
                    <div class="col-md-2">
                        <label class="form-label">日志级别</label>
                        <select class="form-select" id="log-level" name="level">
                            <option value="">全部</option>
                            <option value="DEBUG">DEBUG</option>
                            <option value="INFO">INFO</option>
                            <option value="WARNING">WARNING</option>
                            <option value="ERROR">ERROR</option>
                            <option value="CRITICAL">CRITICAL</option>
                        </select>
                    </div>
                    <div class="col-md-2">
                        <label class="form-label">日志来源</label>
                        <select class="form-select" id="log-source" name="source">
                            <option value="">全部</option>
                            <option value="django">Django</option>
                            <option value="celery">Celery</option>
                            <option value="application">应用</option>
                            <option value="system">系统</option>
                        </select>
                    </div>
                    <div class="col-md-2">
                        <label class="form-label">开始时间</label>
                        <input type="datetime-local" class="form-control" id="start-time" name="start_time">
                    </div>
                    <div class="col-md-2">
                        <label class="form-label">结束时间</label>
                        <input type="datetime-local" class="form-control" id="end-time" name="end_time">
                    </div>
                    <div class="col-md-3">
                        <label class="form-label">关键词搜索</label>
                        <input type="text" class="form-control" id="search-keyword" name="keyword" placeholder="搜索日志内容...">
                    </div>
                    <div class="col-md-1">
                        <label class="form-label">&nbsp;</label>
                        <button type="submit" class="btn btn-primary w-100">
                            <i class="fas fa-search"></i>
                        </button>
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>

<!-- 日志统计 -->
<div class="row mb-4">
    <div class="col-md-3">
        <div class="stat-card">
            <div class="stat-icon bg-info">
                <i class="fas fa-list"></i>
            </div>
            <div class="stat-content">
                <h3 id="total-logs">-</h3>
                <p>总日志数</p>
            </div>
        </div>
    </div>
    <div class="col-md-3">
        <div class="stat-card">
            <div class="stat-icon bg-danger">
                <i class="fas fa-exclamation-triangle"></i>
            </div>
            <div class="stat-content">
                <h3 id="error-logs">-</h3>
                <p>错误日志</p>
            </div>
        </div>
    </div>
    <div class="col-md-3">
        <div class="stat-card">
            <div class="stat-icon bg-warning">
                <i class="fas fa-exclamation"></i>
            </div>
            <div class="stat-content">
                <h3 id="warning-logs">-</h3>
                <p>警告日志</p>
            </div>
        </div>
    </div>
    <div class="col-md-3">
        <div class="stat-card">
            <div class="stat-icon bg-success">
                <i class="fas fa-clock"></i>
            </div>
            <div class="stat-content">
                <h3 id="recent-logs">-</h3>
                <p>最近1小时</p>
            </div>
        </div>
    </div>
</div>

<!-- 日志级别分布 -->
<div class="row mb-4">
    <div class="col-lg-6">
        <div class="card">
            <div class="card-header">
                <h6 class="mb-0">
                    <i class="fas fa-chart-bar me-2"></i>日志级别分布
                </h6>
            </div>
            <div class="card-body">
                <canvas id="logLevelChart" height="200"></canvas>
            </div>
        </div>
    </div>
    <div class="col-lg-6">
        <div class="card">
            <div class="card-header">
                <h6 class="mb-0">
                    <i class="fas fa-chart-line me-2"></i>日志趋势
                </h6>
            </div>
            <div class="card-body">
                <canvas id="logTrendChart" height="200"></canvas>
            </div>
        </div>
    </div>
</div>

<!-- 日志列表 -->
<div class="row">
    <div class="col-12">
        <div class="card">
            <div class="card-header">
                <div class="d-flex justify-content-between align-items-center">
                    <h6 class="mb-0">
                        <i class="fas fa-list me-2"></i>日志记录
                    </h6>
                    <div class="d-flex gap-2 align-items-center">
                        <div class="form-check form-switch">
                            <input class="form-check-input" type="checkbox" id="auto-refresh-logs" checked>
                            <label class="form-check-label" for="auto-refresh-logs">
                                实时刷新
                            </label>
                        </div>
                        <select class="form-select form-select-sm" id="page-size" style="width: auto;">
                            <option value="50">50条/页</option>
                            <option value="100" selected>100条/页</option>
                            <option value="200">200条/页</option>
                        </select>
                        <button type="button" class="btn btn-outline-secondary btn-sm" onclick="refreshLogs()">
                            <i class="fas fa-sync"></i>
                        </button>
                    </div>
                </div>
            </div>
            <div class="card-body p-0">
                <div class="log-container">
                    <div id="log-list" class="log-list">
                        <!-- 日志记录将动态加载 -->
                    </div>
                </div>
                
                <!-- 加载更多 -->
                <div class="text-center p-3" id="load-more-container" style="display: none;">
                    <button type="button" class="btn btn-outline-primary" id="load-more-btn" onclick="loadMoreLogs()">
                        <i class="fas fa-chevron-down"></i> 加载更多
                    </button>
                </div>
                
                <!-- 加载中 -->
                <div class="text-center p-3" id="loading-container" style="display: none;">
                    <div class="spinner-border spinner-border-sm" role="status">
                        <span class="visually-hidden">加载中...</span>
                    </div>
                    <span class="ms-2">加载中...</span>
                </div>
            </div>
        </div>
    </div>
</div>

<!-- 日志详情模态框 -->
<div class="modal fade" id="logDetailModal" tabindex="-1">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">日志详情</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
            </div>
            <div class="modal-body">
                <div class="row mb-3">
                    <div class="col-md-6">
                        <strong>时间:</strong>
                        <span id="detail-timestamp">-</span>
                    </div>
                    <div class="col-md-6">
                        <strong>级别:</strong>
                        <span id="detail-level" class="badge">-</span>
                    </div>
                </div>
                <div class="row mb-3">
                    <div class="col-md-6">
                        <strong>来源:</strong>
                        <span id="detail-source">-</span>
                    </div>
                    <div class="col-md-6">
                        <strong>模块:</strong>
                        <span id="detail-module">-</span>
                    </div>
                </div>
                <div class="mb-3">
                    <strong>消息:</strong>
                    <div class="log-message" id="detail-message">-</div>
                </div>
                <div class="mb-3" id="detail-traceback-container" style="display: none;">
                    <strong>堆栈跟踪:</strong>
                    <pre class="log-traceback" id="detail-traceback"></pre>
                </div>
                <div class="mb-3" id="detail-context-container" style="display: none;">
                    <strong>上下文信息:</strong>
                    <pre class="log-context" id="detail-context"></pre>
                </div>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-outline-secondary" onclick="copyLogDetail()">
                    <i class="fas fa-copy"></i> 复制
                </button>
                <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button>
            </div>
        </div>
    </div>
</div>
{% endblock %}

{% block extra_css %}
<style>
.stat-card {
    background: white;
    border-radius: 8px;
    padding: 20px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    display: flex;
    align-items: center;
    gap: 15px;
}

.stat-icon {
    width: 50px;
    height: 50px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
    font-size: 20px;
}

.stat-content h3 {
    margin: 0;
    font-size: 24px;
    font-weight: bold;
    color: #333;
}

.stat-content p {
    margin: 0;
    color: #666;
    font-size: 14px;
}

.log-container {
    max-height: 600px;
    overflow-y: auto;
    background: #f8f9fa;
}

.log-list {
    font-family: 'Courier New', monospace;
    font-size: 13px;
    line-height: 1.4;
}

.log-entry {
    padding: 8px 15px;
    border-bottom: 1px solid #e9ecef;
    cursor: pointer;
    transition: background-color 0.2s;
}

.log-entry:hover {
    background-color: #e9ecef;
}

.log-entry.level-DEBUG {
    border-left: 3px solid #6c757d;
}

.log-entry.level-INFO {
    border-left: 3px solid #0dcaf0;
}

.log-entry.level-WARNING {
    border-left: 3px solid #ffc107;
}

.log-entry.level-ERROR {
    border-left: 3px solid #dc3545;
}

.log-entry.level-CRITICAL {
    border-left: 3px solid #6f42c1;
    background-color: #f8f9fa;
}

.log-timestamp {
    color: #6c757d;
    font-weight: normal;
}

.log-level {
    font-weight: bold;
    min-width: 60px;
    display: inline-block;
}

.log-level.DEBUG {
    color: #6c757d;
}

.log-level.INFO {
    color: #0dcaf0;
}

.log-level.WARNING {
    color: #ffc107;
}

.log-level.ERROR {
    color: #dc3545;
}

.log-level.CRITICAL {
    color: #6f42c1;
}

.log-source {
    color: #495057;
    font-weight: 500;
    min-width: 80px;
    display: inline-block;
}

.log-message {
    color: #212529;
    word-break: break-word;
    white-space: pre-wrap;
    background: #fff;
    padding: 10px;
    border-radius: 4px;
    border: 1px solid #dee2e6;
    max-height: 200px;
    overflow-y: auto;
}

.log-traceback {
    background: #f8f9fa;
    border: 1px solid #dee2e6;
    border-radius: 4px;
    padding: 10px;
    font-size: 12px;
    max-height: 300px;
    overflow-y: auto;
    white-space: pre-wrap;
    word-break: break-word;
}

.log-context {
    background: #f8f9fa;
    border: 1px solid #dee2e6;
    border-radius: 4px;
    padding: 10px;
    font-size: 12px;
    max-height: 200px;
    overflow-y: auto;
}

.log-highlight {
    background-color: #fff3cd;
    padding: 2px 4px;
    border-radius: 2px;
}

.empty-logs {
    text-align: center;
    padding: 40px;
    color: #6c757d;
}

.empty-logs i {
    font-size: 48px;
    margin-bottom: 15px;
    opacity: 0.5;
}

/* 滚动条样式 */
.log-container::-webkit-scrollbar {
    width: 8px;
}

.log-container::-webkit-scrollbar-track {
    background: #f1f1f1;
}

.log-container::-webkit-scrollbar-thumb {
    background: #c1c1c1;
    border-radius: 4px;
}

.log-container::-webkit-scrollbar-thumb:hover {
    background: #a8a8a8;
}
</style>
{% endblock %}

{% block extra_js %}
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
// 全局变量
let currentPage = 1;
let hasMoreLogs = true;
let isLoading = false;
let refreshInterval;
let charts = {};

// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', function() {
    initializeLogsPage();
});

// 初始化日志页面
function initializeLogsPage() {
    // 加载初始数据
    loadLogStats();
    loadLogs(true);
    
    // 初始化图表
    initializeCharts();
    
    // 绑定事件
    bindEvents();
    
    // 设置自动刷新
    setupAutoRefresh();
    
    // 设置默认时间范围（最近24小时）
    setDefaultTimeRange();
}

// 设置默认时间范围
function setDefaultTimeRange() {
    const now = new Date();
    const yesterday = new Date(now.getTime() - 24 * 60 * 60 * 1000);
    
    document.getElementById('start-time').value = formatDateTimeLocal(yesterday);
    document.getElementById('end-time').value = formatDateTimeLocal(now);
}

// 格式化日期时间为本地格式
function formatDateTimeLocal(date) {
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    const hours = String(date.getHours()).padStart(2, '0');
    const minutes = String(date.getMinutes()).padStart(2, '0');
    
    return `${year}-${month}-${day}T${hours}:${minutes}`;
}

// 加载日志统计
function loadLogStats() {
    fetch('/analytics/ajax/log-stats/')
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            updateLogStats(data.stats);
            updateCharts(data.charts);
        }
    })
    .catch(error => {
        console.error('加载日志统计失败:', error);
    });
}

// 更新日志统计
function updateLogStats(stats) {
    document.getElementById('total-logs').textContent = stats.total_logs || 0;
    document.getElementById('error-logs').textContent = stats.error_logs || 0;
    document.getElementById('warning-logs').textContent = stats.warning_logs || 0;
    document.getElementById('recent-logs').textContent = stats.recent_logs || 0;
}

// 初始化图表
function initializeCharts() {
    // 日志级别分布图
    const levelCtx = document.getElementById('logLevelChart').getContext('2d');
    charts.logLevel = new Chart(levelCtx, {
        type: 'bar',
        data: {
            labels: ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'],
            datasets: [{
                label: '日志数量',
                data: [0, 0, 0, 0, 0],
                backgroundColor: [
                    '#6c757d',
                    '#0dcaf0',
                    '#ffc107',
                    '#dc3545',
                    '#6f42c1'
                ]
            }]
        },
        options: {
            responsive: true,
            maintainAspectRatio: false,
            plugins: {
                legend: {
                    display: false
                }
            },
            scales: {
                y: {
                    beginAtZero: true
                }
            }
        }
    });
    
    // 日志趋势图
    const trendCtx = document.getElementById('logTrendChart').getContext('2d');
    charts.logTrend = new Chart(trendCtx, {
        type: 'line',
        data: {
            labels: [],
            datasets: [
                {
                    label: 'ERROR',
                    data: [],
                    borderColor: '#dc3545',
                    backgroundColor: 'rgba(220, 53, 69, 0.1)',
                    tension: 0.4
                },
                {
                    label: 'WARNING',
                    data: [],
                    borderColor: '#ffc107',
                    backgroundColor: 'rgba(255, 193, 7, 0.1)',
                    tension: 0.4
                },
                {
                    label: 'INFO',
                    data: [],
                    borderColor: '#0dcaf0',
                    backgroundColor: 'rgba(13, 202, 240, 0.1)',
                    tension: 0.4
                }
            ]
        },
        options: {
            responsive: true,
            maintainAspectRatio: false,
            scales: {
                y: {
                    beginAtZero: true
                }
            },
            plugins: {
                legend: {
                    position: 'top'
                }
            }
        }
    });
}

// 更新图表
function updateCharts(chartData) {
    // 更新日志级别分布图
    if (chartData.level_distribution) {
        charts.logLevel.data.datasets[0].data = [
            chartData.level_distribution.DEBUG || 0,
            chartData.level_distribution.INFO || 0,
            chartData.level_distribution.WARNING || 0,
            chartData.level_distribution.ERROR || 0,
            chartData.level_distribution.CRITICAL || 0
        ];
        charts.logLevel.update();
    }
    
    // 更新日志趋势图
    if (chartData.trend) {
        charts.logTrend.data.labels = chartData.trend.labels;
        charts.logTrend.data.datasets[0].data = chartData.trend.error;
        charts.logTrend.data.datasets[1].data = chartData.trend.warning;
        charts.logTrend.data.datasets[2].data = chartData.trend.info;
        charts.logTrend.update();
    }
}

// 加载日志
function loadLogs(reset = false) {
    if (isLoading) return;
    
    if (reset) {
        currentPage = 1;
        hasMoreLogs = true;
    }
    
    isLoading = true;
    showLoading(true);
    
    const formData = new FormData(document.getElementById('log-filter-form'));
    formData.append('page', currentPage);
    formData.append('page_size', document.getElementById('page-size').value);
    
    fetch('/analytics/ajax/logs/', {
        method: 'POST',
        body: formData,
        headers: {
            'X-CSRFToken': CFS.utils.getCsrfToken()
        }
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            if (reset) {
                document.getElementById('log-list').innerHTML = '';
            }
            
            appendLogs(data.logs);
            hasMoreLogs = data.has_more;
            
            updateLoadMoreButton();
        } else {
            CFS.utils.showNotification(data.message || '加载日志失败', 'error');
        }
    })
    .catch(error => {
        console.error('加载日志失败:', error);
        CFS.utils.showNotification('加载日志失败', 'error');
    })
    .finally(() => {
        isLoading = false;
        showLoading(false);
    });
}

// 追加日志到列表
function appendLogs(logs) {
    const logList = document.getElementById('log-list');
    
    if (logs.length === 0 && currentPage === 1) {
        logList.innerHTML = `
            <div class="empty-logs">
                <i class="fas fa-file-alt"></i>
                <p>没有找到符合条件的日志记录</p>
            </div>
        `;
        return;
    }
    
    const html = logs.map(log => {
        const timestamp = CFS.utils.formatDateTime(log.timestamp);
        const levelClass = log.level.toLowerCase();
        
        return `
            <div class="log-entry level-${log.level}" onclick="showLogDetail('${log.id}')">
                <span class="log-timestamp">${timestamp}</span>
                <span class="log-level ${log.level}">[${log.level}]</span>
                <span class="log-source">${log.source}</span>
                <span class="log-message-preview">${escapeHtml(log.message.substring(0, 200))}${log.message.length > 200 ? '...' : ''}</span>
            </div>
        `;
    }).join('');
    
    logList.insertAdjacentHTML('beforeend', html);
}

// 显示/隐藏加载状态
function showLoading(show) {
    const loadingContainer = document.getElementById('loading-container');
    loadingContainer.style.display = show ? 'block' : 'none';
}

// 更新加载更多按钮
function updateLoadMoreButton() {
    const loadMoreContainer = document.getElementById('load-more-container');
    loadMoreContainer.style.display = hasMoreLogs ? 'block' : 'none';
}

// 加载更多日志
function loadMoreLogs() {
    if (!hasMoreLogs || isLoading) return;
    
    currentPage++;
    loadLogs(false);
}

// 刷新日志
function refreshLogs() {
    loadLogStats();
    loadLogs(true);
}

// 显示日志详情
function showLogDetail(logId) {
    fetch(`/analytics/ajax/log-detail/${logId}/`)
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            const log = data.log;
            
            document.getElementById('detail-timestamp').textContent = 
                CFS.utils.formatDateTime(log.timestamp);
            
            const levelBadge = document.getElementById('detail-level');
            levelBadge.textContent = log.level;
            levelBadge.className = `badge bg-${getLevelColor(log.level)}`;
            
            document.getElementById('detail-source').textContent = log.source;
            document.getElementById('detail-module').textContent = log.module || '-';
            document.getElementById('detail-message').textContent = log.message;
            
            // 显示/隐藏堆栈跟踪
            const tracebackContainer = document.getElementById('detail-traceback-container');
            if (log.traceback) {
                document.getElementById('detail-traceback').textContent = log.traceback;
                tracebackContainer.style.display = 'block';
            } else {
                tracebackContainer.style.display = 'none';
            }
            
            // 显示/隐藏上下文信息
            const contextContainer = document.getElementById('detail-context-container');
            if (log.context) {
                document.getElementById('detail-context').textContent = 
                    JSON.stringify(log.context, null, 2);
                contextContainer.style.display = 'block';
            } else {
                contextContainer.style.display = 'none';
            }
            
            // 显示模态框
            const modal = new bootstrap.Modal(document.getElementById('logDetailModal'));
            modal.show();
        } else {
            CFS.utils.showNotification(data.message || '加载日志详情失败', 'error');
        }
    })
    .catch(error => {
        console.error('加载日志详情失败:', error);
        CFS.utils.showNotification('加载日志详情失败', 'error');
    });
}

// 获取级别颜色
function getLevelColor(level) {
    const colors = {
        'DEBUG': 'secondary',
        'INFO': 'info',
        'WARNING': 'warning',
        'ERROR': 'danger',
        'CRITICAL': 'dark'
    };
    return colors[level] || 'secondary';
}

// 复制日志详情
function copyLogDetail() {
    const timestamp = document.getElementById('detail-timestamp').textContent;
    const level = document.getElementById('detail-level').textContent;
    const source = document.getElementById('detail-source').textContent;
    const module = document.getElementById('detail-module').textContent;
    const message = document.getElementById('detail-message').textContent;
    const traceback = document.getElementById('detail-traceback').textContent;
    const context = document.getElementById('detail-context').textContent;
    
    let content = `时间: ${timestamp}\n`;
    content += `级别: ${level}\n`;
    content += `来源: ${source}\n`;
    content += `模块: ${module}\n`;
    content += `消息: ${message}\n`;
    
    if (traceback) {
        content += `\n堆栈跟踪:\n${traceback}\n`;
    }
    
    if (context) {
        content += `\n上下文信息:\n${context}\n`;
    }
    
    navigator.clipboard.writeText(content).then(() => {
        CFS.utils.showNotification('日志详情已复制到剪贴板', 'success');
    }).catch(error => {
        console.error('复制失败:', error);
        CFS.utils.showNotification('复制失败', 'error');
    });
}

// 绑定事件
function bindEvents() {
    // 过滤表单提交
    document.getElementById('log-filter-form').addEventListener('submit', function(e) {
        e.preventDefault();
        loadLogs(true);
    });
    
    // 页面大小变化
    document.getElementById('page-size').addEventListener('change', function() {
        loadLogs(true);
    });
    
    // 实时刷新开关
    document.getElementById('auto-refresh-logs').addEventListener('change', function() {
        if (this.checked) {
            setupAutoRefresh();
        } else {
            if (refreshInterval) {
                clearInterval(refreshInterval);
                refreshInterval = null;
            }
        }
    });
}

// 设置自动刷新
function setupAutoRefresh() {
    if (refreshInterval) {
        clearInterval(refreshInterval);
    }
    
    const autoRefreshCheckbox = document.getElementById('auto-refresh-logs');
    if (autoRefreshCheckbox.checked) {
        refreshInterval = setInterval(() => {
            loadLogStats();
            // 只刷新第一页的日志
            if (currentPage === 1) {
                loadLogs(true);
            }
        }, 10000); // 10秒刷新一次
    }
}

// 重置过滤器
function resetFilters() {
    document.getElementById('log-filter-form').reset();
    setDefaultTimeRange();
    loadLogs(true);
}

// 导出日志
function exportLogs() {
    const formData = new FormData(document.getElementById('log-filter-form'));
    const params = new URLSearchParams(formData);
    
    window.open(`/analytics/export/logs/?${params.toString()}`);
}

// HTML转义
function escapeHtml(text) {
    const div = document.createElement('div');
    div.textContent = text;
    return div.innerHTML;
}

// 页面卸载时清理
window.addEventListener('beforeunload', function() {
    if (refreshInterval) {
        clearInterval(refreshInterval);
    }
});
</script>
{% endblock %}